/////////////////////////////////////////////////////////////////////////////
// Name:        ax_module.h
// Purpose:     AxModule: a self-contained unit of functionality.
//              Implement a new module to tell the framework how to e.g.
//              scan for files of a particular kind.
// Author:      Julian Smart
// Modified by:
// Created:     2009-03-25
// RCS-ID:      $Id$
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _AX_AXMODULE_H_
#define _AX_AXMODULE_H_

#include "wx/config.h"

#include "ax_resource/ax_resource.h"

class AxActivator;

// declare a linked list of modules
class AxModule;
WX_DECLARE_EXPORTED_LIST(AxModule, AxModuleList);

// Priority symbols
#define axHIGHEST_PRIORITY	100
#define axHIGH_PRIORITY		80
#define axMEDIUM_PRIORITY	50
#define axLOW_PRIORITY		20
#define axLOWEST_PRIORITY	0

class AxResourceLibrary;

/**
    @class AxModule

    Classes derived from AxModule define behaviour of
    a chunk of functionality such as an HTML editor.

    Command events unprocessed by the currently focused control
    are sent to each module in turn, stopping when the command
    has been processed.

    @category{ax_resource}
 */

class AxModule: public wxEvtHandler
{
DECLARE_CLASS(AxModule)

public:
    /// Constructor.
    AxModule();

    /// Destructor.
    ~AxModule() {}

// Overridables

    /// Called on IDE startup, before the main window has been created.
    virtual bool OnInit() = 0;

    /// Called on application startup, after the main window has been created.
    virtual bool OnInitUI() = 0;

 	/// Called just before program termination, but only if OnInit()
    /// succeeded.
    virtual void OnExit() = 0;

	/// Read config settings
	virtual bool LoadConfig(wxConfigBase& WXUNUSED(config)) { return true; }

	/// Write config settings
    virtual bool SaveConfig(wxConfigBase& WXUNUSED(config)) { return true; }

    // Called just before the frame is closed. Return false vetoes
    // the frame/app close.
    virtual bool OnCloseMainWindow() { return true; }

    // Allows app to search amongst its own objects. Call AxResourceLibrary::AddSearchItem
    // for each item.
    virtual bool OnSearch(const wxString& WXUNUSED(searchString), int WXUNUSED(flags), AxResourceLibrary* WXUNUSED(library)) { return false; }

    /// Is this file supported?
    virtual bool IsFileSupported(const wxString& WXUNUSED(filename)) { return false; }

    /// Load the file into a new AxResource
    virtual AxResource* LoadResource(const wxString& WXUNUSED(filename)) { return false; }

    /// Aggregate any files that belong together and add to resources. Return false if you don't
    /// aggregate any files.
    virtual bool AggregateFiles(AxResourceLibrary* WXUNUSED(library), wxArrayString& WXUNUSED(files), bool WXUNUSED(checkIfFileLoaded)) { return false; }

    /// Create an activator for the resource, for creating views and further menu items.
    virtual AxActivator* CreateActivator(AxResourceLibrary* WXUNUSED(library), AxResource* WXUNUSED(resource)) { return NULL; }

    /// TODO: priorities for e.g. initialisation.

// Operations

    /// Finds the module with the given wxClassInfo
    static AxModule* FindModule(wxClassInfo* info);

// Implementation

    bool Init(AxResourceLibrary* library) { m_library = library; return OnInit(); }
    void Exit() { OnExit(); }
    static void RegisterModule(AxModule* module);
    static void RegisterModules();
    static bool InitializeModules(AxResourceLibrary* library);
    static void CleanUpModules();
    static void UnregisterModule(AxModule* module);
    static AxModuleList& GetModules() { return m_modules; }

// Accessors

	/// Set the priority: 0 is lowest, 100 is highest
	void SetPriority(int priority) { m_priority = priority; }
	int GetPriority() { return m_priority; }
    
    AxResourceLibrary* GetLibrary() const { return m_library; }
    void SetLibrary(AxResourceLibrary* library) { m_library = library; }

protected:
    static AxModuleList m_modules;

	int	m_priority;
    AxResourceLibrary* m_library;
};

#endif
    // _AX_AXMODULE_H_

